#pragma once

#include "..\\headers.default.h"
#include "..\\headers.ipfe.h"

#include "NodeInstance.h"

using namespace loirey;

#define	AND_OR_TREE_FEATURE_MODE	0

namespace and_or_tree
{
	class CAbstractNode
	{
	public:
		static const int TYPE_OR = 0;
		static const int TYPE_AND = 1;
		static const int TYPE_LEAF = 2;
	public:
		int NodeIndex;
		int LayerIndex;
		int IndexInLayer;
		CSimpleTypeArray<int> ChildrenIndexList;
		CSimpleTypeArray<int> NodeIndexOfSubTreeLeafNodeList;
		CSimpleTypeArray<int> LeafIndexOfSubTreeLeafNodeList;

	public:
		int GetChildrenAmount() const;
		const int* GetPtrChildrenIndex() const;
	public:
		int GetSubTreeLeafNodeAmount() const;
		const int* GetPtrNodeIndexOfSubTreeLeafNode() const;
		const int* GetPtrLeafIndexOfSubTreeLeafNode() const;
	public:
		virtual int GetType() const = 0;
	public:
		virtual int GetShapeFeatureDimension() const = 0;
		virtual int GetAppearanceFeatureDimension() const = 0;
		virtual void ComputeShapeFeature(
			CSimpleTypeArray<double>& DstShapeFeatureList,
			const CParsedInstance* pSrcMyInstance,
			const CSimpleTypeArray<const CParsedInstance*>& SrcChildrenInstancePtrList
			) const = 0;
		virtual void ComputeAppearanceFeature(
			CSimpleTypeArray<double>& DstAppearanceFeatureList,
			const CParsedInstance* pSrcMyInstance
			) const = 0;
	public:
		//virtual void ExtractParsedInstance(
		//	CParsedInstance* pDstParsedInstance,
		//	const CSimpleTypeArray<const CParsedInstance*>& ChildrenPiptrList
		//	) const = 0;
	};

	class COrNode : public CAbstractNode
	{
	public:
		virtual int GetType() const;
	public:
		virtual int GetShapeFeatureDimension() const;
		virtual int GetAppearanceFeatureDimension() const;
		virtual void ComputeShapeFeature(
			CSimpleTypeArray<double>& DstShapeFeatureList,
			const CParsedInstance* pSrcMyInstance,
			const CSimpleTypeArray<const CParsedInstance*>& SrcChildrenInstancePtrList
			) const;
		virtual void ComputeAppearanceFeature(
			CSimpleTypeArray<double>& DstAppearanceFeatureList,
			const CParsedInstance* pSrcMyInstance
			) const;
	public:
		//virtual void ExtractParsedInstance(
		//	CParsedInstance* pDstParsedInstance,
		//	const CSimpleTypeArray<const CParsedInstance*>& ChildrenPiptrList
		//	) const;
	};

	class CAndNode : public CAbstractNode
	{
	public:
		virtual int GetType() const;
	public:
		virtual int GetShapeFeatureDimension() const;
		virtual int GetAppearanceFeatureDimension() const;
		virtual void ComputeShapeFeature(
			CSimpleTypeArray<double>& DstShapeFeatureList,
			const CParsedInstance* pSrcMyInstance,
			const CSimpleTypeArray<const CParsedInstance*>& SrcChildrenInstancePtrList
			) const;
		virtual void ComputeAppearanceFeature(
			CSimpleTypeArray<double>& DstAppearanceFeatureList,
			const CParsedInstance* pSrcMyInstance
			) const;
	public:
		//virtual void ExtractParsedInstance(
		//	CParsedInstance* pDstParsedInstance,
		//	const CSimpleTypeArray<const CParsedInstance*>& ChildrenPiptrList
		//	) const;
	};

	class CLeafNode : public CAbstractNode
	{
	public:
		static CImagePositionFeatureExtractor* pIPFE_Prototype;
		static int AppearanceFeatureDimension;
		static CImagePyramidPositionFeatureExtractor* pCurrentIPPFE;

	public:
		static void InitIPFE(CImagePositionFeatureExtractor* pInitialized_IPFE_Prototype);
		static void SetCurrentIPPFE(CImagePyramidPositionFeatureExtractor* pIPPFE);
	public:
		virtual int GetType() const;
	public:
		virtual int GetShapeFeatureDimension() const;
		virtual int GetAppearanceFeatureDimension() const;
		virtual void ComputeShapeFeature(
			CSimpleTypeArray<double>& DstShapeFeatureList,
			const CParsedInstance* pSrcMyInstance,
			const CSimpleTypeArray<const CParsedInstance*>& SrcChildrenInstancePtrList
			) const;
		virtual void ComputeAppearanceFeature(
			CSimpleTypeArray<double>& DstAppearanceFeatureList,
			const CParsedInstance* pSrcMyInstance
			) const;
	public:
		//virtual void ExtractParsedInstance(
		//	CParsedInstance* pDstParsedInstance,
		//	const CSimpleTypeArray<const CParsedInstance*>& ChildrenPiptrList
		//	) const;
	};

	class CAbstractTree
	{
	public:
		int NodeAmount;
		int LayerAmount;
		int LeafNodeAmount;
		int EdgeAmount;
		CSimpleTypeArray<CAbstractNode*> PtrNodeList;
		CSimpleTypeArray<int> LayerStartList;
		CSimpleTypeArray<int> LeafNodeIndexList;
		CSimpleTypeArray<bool> AreAncestorRelation;
		//CSimpleTypeArray<int> EdgeIndexBase;
		CSimpleTypeArray<int> NodeColorList;
	
	protected:
		void myRelease();
	public:
		CAbstractTree();
		~CAbstractTree();
	public:
		bool Is_A_AncestorOf_B(int A, int B) const;
	public:
		const int* GetPtrLeafNodeIndex() const;
	public:
		int GetRootIndex() const;
		int GetNodeIndex(int LayerIndex, int NodeIndexInLayer) const;
		int GetLeafNodeIndex(int LeafIndex) const;
		//int GetNodeEdgeIndexBase(int NodeIndex) const;
		const CAbstractNode* GetNode(int NodeIndex) const;
		const CAbstractNode* GetRoot() const;
		const CAbstractNode* GetNode(int LayerIndex, int NodeIndexInLayer) const;
	public:
		void myInit(string strFN_AbstractTree);
	public:
		static int TranslateColor(int R, int G, int B);
	public:
		int GetNodeColor(int NodeIndex) const;
	};
}

